from abc import ABC

import pymysql
from dbutils.pooled_db import PooledDB
from pymysql.cursors import Cursor

from env_config import SF

"""
适配现有逻辑
"""


def get_connection(self) -> pymysql.Connection:
    return self.connection()


def db_query(self, query, args=()):
    try:
        self.execute(query, args)
        return self.fetchall()
    except Exception as ex:
        raise ex


def db_modify(self, query, args=(), exec_many=False):
    try:
        if not exec_many:
            self.execute(query, args)
        else:
            self.executemany(query, args)
        return {'rowcount': self.rowcount, 'lastrowid': self.lastrowid}
    except Exception as ex:
        raise ex


# Monkey Patching
PooledDB.get_connection = get_connection
Cursor.db_query = db_query
Cursor.db_modify = db_modify


class SF_DB(object):
    # 数据库读取数据 超时时间
    DB_READ_TIMEOUT_SECONDS = 20

    _instance = None

    _pool: PooledDB = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return cls._instance

    def __init__(self):
        self._pool = PooledDB(creator=pymysql, maxconnections=20, mincached=2, maxcached=5, blocking=True,
                              host=SF.DB_HOST, port=SF.DB_PORT, user=SF.DB_USER, password=SF.DB_PASSWORD,
                              db=SF.DB_DEFAULT_DB,
                              connect_timeout=SF.DB_WAIT_TIMEOUT, read_timeout=self.DB_READ_TIMEOUT_SECONDS,
                              autocommit=True)

    def get_pool(self) -> PooledDB:
        return self._pool


class DBDevice(ABC):

    def __init__(self, *args, **kwargs):
        for k in kwargs:
            if hasattr(self, k):
                setattr(self, k, kwargs[k])
